package com.xueyi.workflow.util;

import com.xueyi.workflow.domain.dto.GraphSchema;
import java.util.*;
import java.lang.reflect.Field;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 原有的 BPMN XML 生成器（已废弃，保留用于向后兼容）
 * 建议使用新的 AbstractBpmnGenerator 架构
 * 
 * @author xueyi
 * @deprecated 使用 AbstractBpmnGenerator 替代
 */
@Deprecated
public class LegacyBpmnGenerator {
    /**
     * 生成 BPMN XML
     * 
     * @param schema 流程图数据
     * @param processId 流程ID
     * @param processName 流程名称
     * @return BPMN XML 字符串
     */
    public static String generateBpmnXml(GraphSchema schema, String processId, String processName) {
        StringBuilder bpmn = new StringBuilder();
        
        // 1. 收集全局信号/消息定义
        Set<String> signalSet = new HashSet<>();
        Set<String> messageSet = new HashSet<>();
        for (GraphSchema.FlowNode node : schema.getNodes()) {
            if ("boundaryEvent".equals(node.getType())) {
                String eventType = (String) node.getData().getOrDefault("eventType", "");
                if ("signal".equals(eventType)) {
                    signalSet.add((String) node.getData().getOrDefault("signalRef", "signal1"));
                } else if ("message".equals(eventType)) {
                    messageSet.add((String) node.getData().getOrDefault("messageRef", "msg1"));
                }
            }
        }
        
        // 2. 生成 XML 头部
        bpmn.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        bpmn.append("<definitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:flowable=\"http://flowable.org/bpmn\" targetNamespace=\"http://www.flowable.org/processdef\">\n");
        
        // 3. 全局信号定义
        for (String sig : signalSet) {
            bpmn.append("  <signal id=\"").append(sig).append("\" name=\"").append(sig).append("\" />\n");
        }
        
        // 4. 全局消息定义
        for (String msg : messageSet) {
            bpmn.append("  <message id=\"").append(msg).append("\" name=\"").append(msg).append("\" />\n");
        }
        
        // 5. 开始流程定义
        bpmn.append("  <process id=\"").append(processId).append("\" name=\"").append(processName).append("\" isExecutable=\"true\">\n");

        // 6. 生成节点
        for (GraphSchema.FlowNode node : schema.getNodes()) {
            generateNodeXml(bpmn, node);
        }
        
        // 7. 生成连线
        for (GraphSchema.FlowEdge edge : schema.getEdges()) {
            generateEdgeXml(bpmn, edge);
        }
        
        // 8. 结束流程定义
        bpmn.append("  </process>\n</definitions>\n");
        return bpmn.toString();
    }

    /**
     * 生成节点 XML
     */
    private static void generateNodeXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        switch (node.getType()) {
            case "start":
            case "input":
            case "event": // VueFlow事件节点
                generateEventNodeXml(bpmn, node);
                break;
            case "end":
            case "output":
                generateEndEventXml(bpmn, node);
                break;
            case "userTask":
            case "default": // 修正：default类型也生成userTask，避免IDREF未绑定
                generateUserTaskXml(bpmn, node);
                break;
            case "serviceTask":
            case "task": // VueFlow任务节点
                generateServiceTaskXml(bpmn, node);
                break;
            case "scriptTask":
                generateScriptTaskXml(bpmn, node);
                break;
            case "condition":
            case "exclusiveGateway":
                generateExclusiveGatewayXml(bpmn, node);
                break;
            case "parallelGateway":
                generateParallelGatewayXml(bpmn, node);
                break;
            case "eventBasedGateway":
                generateEventBasedGatewayXml(bpmn, node);
                break;
            case "gateway": {
                generateGatewayXml(bpmn, node);
                break;
            }
            case "boundaryEvent": {
                generateBoundaryEventXml(bpmn, node);
                break;
            }
            case "cc": // 抄送节点用serviceTask+扩展属性
                generateCcNodeXml(bpmn, node);
                break;
            case "subProcess": {
                generateSubProcessXml(bpmn, node);
                break;
            }
            // 可扩展更多类型
        }
    }

    /**
     * 生成连线 XML
     * 核心逻辑：检查连线是否包含条件表达式，如果有则生成带条件的连线
     */
    private static void generateEdgeXml(StringBuilder bpmn, GraphSchema.FlowEdge edge) {
        // 1. 生成连线基础信息
        bpmn.append("    <sequenceFlow id=\"").append(edge.getSource()).append("_to_").append(edge.getTarget())
            .append("\" sourceRef=\"").append(edge.getSource()).append("\" targetRef=\"").append(edge.getTarget()).append("\"");
        
        // 2. 检查连线是否包含条件表达式
        // 注意：这里需要将 FlowEdge 转换为 Map 来访问所有字段
        // 因为 GraphSchema.FlowEdge 只包含 source 和 target 字段
        // 但实际的 VueFlow 数据包含更多字段，包括条件表达式
        Map<String, Object> edgeMap = convertFlowEdgeToMap(edge);
        
        // 3. 处理条件表达式
        if (hasConditionExpression(edgeMap)) {
            generateConditionalFlowXml(bpmn, edgeMap);
        } else {
            // 4. 生成无条件连线
            bpmn.append(" />\n");
        }
    }

    /**
     * 检查连线是否包含条件表达式
     */
    private static boolean hasConditionExpression(Map<String, Object> edgeMap) {
        // 检查连线对象本身的条件字段
        String conditionType = (String) edgeMap.get("conditionType");
        if (conditionType != null && !conditionType.trim().isEmpty()) {
            if ("expression".equals(conditionType)) {
                String conditionExpression = (String) edgeMap.get("conditionExpression");
                return conditionExpression != null && !conditionExpression.trim().isEmpty();
            } else if ("script".equals(conditionType)) {
                String scriptContent = (String) edgeMap.get("scriptContent");
                return scriptContent != null && !scriptContent.trim().isEmpty();
            }
        }
        
        // 检查 data 字段中的条件配置
        Object edgeData = edgeMap.get("data");
        if (edgeData instanceof Map) {
            Map<String, Object> dataMap = (Map<String, Object>) edgeData;
            String dataConditionType = (String) dataMap.get("conditionType");
            if (dataConditionType != null && !dataConditionType.trim().isEmpty()) {
                if ("expression".equals(dataConditionType)) {
                    String conditionExpression = (String) dataMap.get("conditionExpression");
                    return conditionExpression != null && !conditionExpression.trim().isEmpty();
                } else if ("script".equals(dataConditionType)) {
                    String scriptContent = (String) dataMap.get("scriptContent");
                    return scriptContent != null && !scriptContent.trim().isEmpty();
                }
            }
        }
        
        return false;
    }

    /**
     * 生成带条件的连线 XML
     */
    private static void generateConditionalFlowXml(StringBuilder bpmn, Map<String, Object> edgeMap) {
        // 1. 检查连线对象本身的条件字段
        String conditionType = (String) edgeMap.get("conditionType");
        if ("expression".equals(conditionType)) {
            String conditionExpression = (String) edgeMap.get("conditionExpression");
            if (conditionExpression != null && !conditionExpression.trim().isEmpty()) {
                bpmn.append(">\n      <conditionExpression xsi:type=\"tFormalExpression\">")
                    .append(conditionExpression)
                    .append("</conditionExpression>\n    </sequenceFlow>\n");
                return;
            }
        } else if ("script".equals(conditionType)) {
            String scriptLanguage = (String) edgeMap.getOrDefault("scriptLanguage", "javascript");
            String scriptContent = (String) edgeMap.get("scriptContent");
            if (scriptContent != null && !scriptContent.trim().isEmpty()) {
                bpmn.append(">\n      <conditionExpression xsi:type=\"tFormalExpression\" language=\"").append(scriptLanguage).append("\">")
                    .append(scriptContent)
                    .append("</conditionExpression>\n    </sequenceFlow>\n");
                return;
            }
        }
        
        // 2. 检查 data 字段中的条件配置
        Object edgeData = edgeMap.get("data");
        if (edgeData instanceof Map) {
            Map<String, Object> dataMap = (Map<String, Object>) edgeData;
            String dataConditionType = (String) dataMap.get("conditionType");
            if ("expression".equals(dataConditionType)) {
                String conditionExpression = (String) dataMap.get("conditionExpression");
                if (conditionExpression != null && !conditionExpression.trim().isEmpty()) {
                    bpmn.append(">\n      <conditionExpression xsi:type=\"tFormalExpression\">")
                        .append(conditionExpression)
                        .append("</conditionExpression>\n    </sequenceFlow>\n");
                    return;
                }
            } else if ("script".equals(dataConditionType)) {
                String scriptLanguage = (String) dataMap.getOrDefault("scriptLanguage", "javascript");
                String scriptContent = (String) dataMap.get("scriptContent");
                if (scriptContent != null && !scriptContent.trim().isEmpty()) {
                    bpmn.append(">\n      <conditionExpression xsi:type=\"tFormalExpression\" language=\"").append(scriptLanguage).append("\">")
                        .append(scriptContent)
                        .append("</conditionExpression>\n    </sequenceFlow>\n");
                    return;
                }
            }
        }
        
        // 3. 如果没有找到条件，生成无条件连线（兜底）
        bpmn.append(" />\n");
    }

    /**
     * 将 FlowEdge 对象转换为 Map，以便访问所有字段
     * 这是关键：GraphSchema.FlowEdge 只包含 source 和 target
     * 但实际的 VueFlow 数据包含更多字段，包括条件表达式
     */
    private static Map<String, Object> convertFlowEdgeToMap(GraphSchema.FlowEdge edge) {
        Map<String, Object> edgeMap = new HashMap<>();
        try {
            // 获取 FlowEdge 的所有字段
            java.lang.reflect.Field[] fields = GraphSchema.FlowEdge.class.getDeclaredFields();
            for (java.lang.reflect.Field field : fields) {
                field.setAccessible(true); // 允许访问私有字段
                edgeMap.put(field.getName(), field.get(edge));
            }
        } catch (Exception e) {
            System.err.println("Error converting FlowEdge to Map: " + e.getMessage());
        }
        return edgeMap;
    }

    /**
     * 生成事件节点 XML
     */
    private static void generateEventNodeXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        String eventType = (String) node.getData().getOrDefault("eventType", "start");
        if ("start".equals(eventType)) {
            bpmn.append("    <startEvent id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "开始")).append("\" />\n");
        } else if ("end".equals(eventType)) {
            bpmn.append("    <endEvent id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "结束")).append("\" />\n");
        } else {
            bpmn.append("    <startEvent id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "开始")).append("\" />\n");
        }
    }

    /**
     * 生成结束事件节点 XML
     */
    private static void generateEndEventXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <endEvent id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "结束")).append("\" />\n");
    }

    /**
     * 生成用户任务节点 XML
     */
    private static void generateUserTaskXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <userTask id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "用户任务")).append("\"");
        
        // 处理人员配置：assignee/candidateUsers/candidateGroups
        Object assignees = node.getData().get("assignees");
        List<String> groups = new ArrayList<>();
        if (assignees instanceof List && !((List<?>)assignees).isEmpty()) {
            List<Map<String, Object>> assigneeList = (List<Map<String, Object>>) assignees;
            
            // 收集不同类型的处理人
            List<String> users = new ArrayList<>();
            List<String> roles = new ArrayList<>();
            List<String> depts = new ArrayList<>();
            List<String> posts = new ArrayList<>();
            String assignee = null;
            
            for (Map<String, Object> assigneeMap : assigneeList) {
                String type = (String) assigneeMap.get("type");
                Object value = assigneeMap.get("value");
                
                if ("user".equals(type) && value instanceof List) {
                    List<?> userList = (List<?>) value;
                    for (Object user : userList) {
                        if (user instanceof Map) {
                            String userId = String.valueOf(((Map<?, ?>) user).get("id"));
                            users.add(userId);
                            // 只有当只有一个用户时才设置为assignee
                            if (assignee == null && userList.size() == 1) {
                                assignee = userId;
                            }
                        } else if (user instanceof String) {
                            users.add((String) user);
                            if (assignee == null && userList.size() == 1) {
                                assignee = (String) user;
                            }
                        }
                    }
                } else if ("role".equals(type) && value instanceof List) {
                    List<?> roleList = (List<?>) value;
                    for (Object role : roleList) {
                        if (role instanceof Map) {
                            String roleId = String.valueOf(((Map<?, ?>) role).get("id"));
                            roles.add(roleId);
                        } else if (role instanceof String) {
                            roles.add((String) role);
                        }
                    }
                } else if ("dept".equals(type) && value instanceof List) {
                    List<?> deptList = (List<?>) value;
                    for (Object dept : deptList) {
                        if (dept instanceof Map) {
                            String deptId = String.valueOf(((Map<?, ?>) dept).get("id"));
                            depts.add(deptId);
                        } else if (dept instanceof String) {
                            depts.add((String) dept);
                        }
                    }
                } else if ("post".equals(type) && value instanceof List) {
                    List<?> postList = (List<?>) value;
                    for (Object post : postList) {
                        if (post instanceof Map) {
                            String postId = String.valueOf(((Map<?, ?>) post).get("id"));
                            posts.add(postId);
                        } else if (post instanceof String) {
                            posts.add((String) post);
                        }
                    }
                } else if ("expression".equals(type) && value instanceof List) {
                    // 处理表达式类型，如流程发起人、部门负责人等
                    List<?> exprList = (List<?>) value;
                    for (Object expr : exprList) {
                        if (expr instanceof Map) {
                            String expression = String.valueOf(((Map<?, ?>) expr).get("expression"));
                            if (expression != null && !expression.trim().isEmpty()) {
                                // 对于表达式类型，只有当只有一个表达式时才设置为assignee
                                if (assignee == null && exprList.size() == 1) {
                                    assignee = expression;
                                }
                                // 将表达式添加到候选组中，用于后续处理
                                groups.add("expr:" + expression);
                            }
                        } else if (expr instanceof String) {
                            String expression = (String) expr;
                            if (assignee == null && exprList.size() == 1) {
                                assignee = expression;
                            }
                            groups.add("expr:" + expression);
                        }
                    }
                }
            }
            
            // 设置assignee（只有当只有一个处理人时才设置）
            if (assignee != null) {
                bpmn.append(" flowable:assignee=\"").append(assignee).append("\"");
            }
            
            // 设置candidateUsers（所有用户）
            if (!users.isEmpty()) {
                bpmn.append(" flowable:candidateUsers=\"").append(String.join(",", users)).append("\"");
            }
            
            // 设置candidateGroups（角色、部门、岗位、表达式）
            groups.addAll(roles);
            groups.addAll(depts);
            groups.addAll(posts);
            if (!groups.isEmpty()) {
                bpmn.append(" flowable:candidateGroups=\"").append(String.join(",", groups)).append("\"");
            }
        }
        
        bpmn.append(">");
        
        // 收集所有扩展元素
        StringBuilder extensionElements = new StringBuilder();
        
        // 监听器
        Object listeners = node.getData().get("listeners");
        if (listeners instanceof List) {
            for (Object l : (List<?>)listeners) {
                if (l instanceof Map) {
                    Map listener = (Map)l;
                    extensionElements.append("<flowable:taskListener event=\"")
                        .append(listener.getOrDefault("event", "create")).append("\"");
                    if ("custom".equals(listener.get("type"))) {
                        extensionElements.append(" class=\"").append(listener.getOrDefault("class", "")).append("\"");
                    }
                    extensionElements.append(" />");
                }
            }
        }
        
        // 添加自定义任务监听器，用于处理用户、角色、部门、岗位到用户的映射
        // 为所有用户任务节点都添加，确保人员配置能正确处理
        extensionElements.append("<flowable:taskListener event=\"create\" class=\"com.xueyi.workflow.listener.CustomTaskListener\" />");
        
        // 抄送配置
        Object cc = node.getData().get("cc");
        Object notifyMethods = node.getData().get("notifyMethods");
        if (cc != null || notifyMethods != null) {
            if (cc != null) {
                extensionElements.append("<flowable:field name=\"cc\" stringValue=\"")
                    .append(cc.toString().replaceAll("\"", "'"))
                    .append("\" />");
            }
            if (notifyMethods != null) {
                extensionElements.append("<flowable:field name=\"notifyMethods\" stringValue=\"")
                    .append(notifyMethods.toString().replaceAll("\"", "'"))
                    .append("\" />");
            }
        }
        
        // 如果有扩展元素，添加extensionElements标签
        if (extensionElements.length() > 0) {
            bpmn.append("<extensionElements>").append(extensionElements).append("</extensionElements>");
        }
        
        // 会签（多实例）
        Object countersign = node.getData().get("countersign");
        if (countersign instanceof Map) {
            Map countersignMap = (Map)countersign;
            String countersignType = (String) countersignMap.get("type");
            // 只有当type不为null且不为空字符串时才生成多实例配置
            if (countersignType != null && !countersignType.trim().isEmpty()) {
                bpmn.append("<multiInstanceLoopCharacteristics isSequential=\"")
                    .append("serial".equals(countersignType) ? "true" : "false")
                    .append("\">");
                
                // 处理循环数据源
                String loopDataInputRef = (String) countersignMap.get("loopDataInputRef");
                if ("assigneeList".equals(loopDataInputRef)) {
                    // 根据人员配置自动生成循环数据
                    bpmn.append("<loopDataInputRef>assigneeList</loopDataInputRef>");
                    bpmn.append("<inputDataItem name=\"assigneeList\" />");
                } else if ("customVariable".equals(loopDataInputRef)) {
                    // 使用自定义变量
                    String customVariableName = (String) countersignMap.get("customVariableName");
                    if (customVariableName != null && !customVariableName.trim().isEmpty()) {
                        bpmn.append("<loopDataInputRef>").append(customVariableName).append("</loopDataInputRef>");
                    } else {
                        // 默认使用assigneeList
                        bpmn.append("<loopDataInputRef>assigneeList</loopDataInputRef>");
                    }
                } else {
                    // 默认使用loopCardinality，根据人员数量设置
                    int assigneeCount = getAssigneeCount(assignees);
                    if (assigneeCount > 0) {
                        bpmn.append("<loopCardinality>").append(assigneeCount).append("</loopCardinality>");
                    } else {
                        bpmn.append("<loopCardinality>1</loopCardinality>");
                    }
                }
                
                // 处理完成条件
                String completionType = (String) countersignMap.get("completionType");
                if ("all".equals(completionType)) {
                    // 全部完成
                    bpmn.append("<completionCondition>${nrOfCompletedInstances == nrOfInstances}</completionCondition>");
                } else if ("minPass".equals(completionType)) {
                    // 最少通过数
                    Object minPass = countersignMap.get("minPass");
                    if (minPass != null) {
                        bpmn.append("<completionCondition>${nrOfCompletedInstances >= ").append(minPass).append("}</completionCondition>");
                    }
                } else if ("maxPass".equals(completionType)) {
                    // 最多通过数
                    Object maxPass = countersignMap.get("maxPass");
                    if (maxPass != null) {
                        bpmn.append("<completionCondition>${nrOfCompletedInstances >= ").append(maxPass).append("}</completionCondition>");
                    }
                } else if ("percentage".equals(completionType)) {
                    // 百分比
                    Object percentage = countersignMap.get("percentage");
                    if (percentage != null) {
                        bpmn.append("<completionCondition>${nrOfCompletedInstances >= (nrOfInstances * ").append(percentage).append(" / 100)}</completionCondition>");
                    }
                } else {
                    // 默认：最少通过数（兼容旧版本）
                    Object minPass = countersignMap.get("minPass");
                    if (minPass != null) {
                        bpmn.append("<completionCondition>${nrOfCompletedInstances >= ").append(minPass).append("}</completionCondition>");
                    }
                }
                
                bpmn.append("</multiInstanceLoopCharacteristics>");
            }
        }
        
        bpmn.append("</userTask>\n");
    }

    /**
     * 生成服务任务节点 XML
     */
    private static void generateServiceTaskXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <serviceTask id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "服务任务")).append("\"");
        // 服务任务配置
        Object serviceClass = node.getData().get("serviceClass");
        if (serviceClass != null) {
            bpmn.append(" flowable:class=\"").append(serviceClass.toString()).append("\"");
        }
        bpmn.append(">");
        
        // 抄送配置
        Object serviceCc = node.getData().get("cc");
        Object serviceNotifyMethods = node.getData().get("notifyMethods");
        if (serviceCc != null || serviceNotifyMethods != null) {
            bpmn.append("<extensionElements>");
            if (serviceCc != null) {
                bpmn.append("<flowable:field name=\"cc\" stringValue=\"")
                    .append(serviceCc.toString().replaceAll("\"", "'"))
                    .append("\" />");
            }
            if (serviceNotifyMethods != null) {
                bpmn.append("<flowable:field name=\"notifyMethods\" stringValue=\"")
                    .append(serviceNotifyMethods.toString().replaceAll("\"", "'"))
                    .append("\" />");
            }
            bpmn.append("</extensionElements>");
        }
        bpmn.append("</serviceTask>\n");
    }

    /**
     * 生成脚本任务节点 XML
     */
    private static void generateScriptTaskXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <scriptTask id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "脚本任务")).append("\" scriptFormat=\"groovy\">");
        Object script = node.getData().get("script");
        if (script != null) bpmn.append(script);
        bpmn.append("</scriptTask>\n");
    }

    /**
     * 生成条件网关节点 XML
     */
    private static void generateExclusiveGatewayXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <exclusiveGateway id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "条件网关")).append("\" />\n");
    }

    /**
     * 生成并行网关节点 XML
     */
    private static void generateParallelGatewayXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <parallelGateway id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "并行网关")).append("\" />\n");
    }

    /**
     * 生成事件网关节点 XML
     */
    private static void generateEventBasedGatewayXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <eventBasedGateway id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "事件网关")).append("\" />\n");
    }

    /**
     * 生成网关节点 XML
     */
    private static void generateGatewayXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        // 根据网关类型生成不同的网关
        String gatewayType = (String) node.getData().getOrDefault("gatewayType", "exclusive");
        String gatewayName = (String) node.getData().getOrDefault("label", "网关");
        switch (gatewayType) {
            case "exclusive":
                bpmn.append("    <exclusiveGateway id=\"").append(node.getId()).append("\" name=\"").append(gatewayName).append("\" />\n");
                break;
            case "parallel":
                bpmn.append("    <parallelGateway id=\"").append(node.getId()).append("\" name=\"").append(gatewayName).append("\" />\n");
                break;
            case "event":
                bpmn.append("    <eventBasedGateway id=\"").append(node.getId()).append("\" name=\"").append(gatewayName).append("\" />\n");
                break;
            default:
                bpmn.append("    <exclusiveGateway id=\"").append(node.getId()).append("\" name=\"").append(gatewayName).append("\" />\n");
                break;
        }
    }

    /**
     * 生成边界事件节点 XML
     */
    private static void generateBoundaryEventXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <boundaryEvent id=\"").append(node.getId()).append("\" attachedToRef=\"").append(node.getData().getOrDefault("attachedTo", "")).append("\">");
        String eventType2 = (String) node.getData().getOrDefault("eventType", "timer");
        if ("timer".equals(eventType2)) {
            bpmn.append("<timerEventDefinition><timeDuration>").append(node.getData().getOrDefault("duration", "PT1H")).append("</timeDuration></timerEventDefinition>");
        } else if ("signal".equals(eventType2)) {
            bpmn.append("<signalEventDefinition signalRef=\"").append(node.getData().getOrDefault("signalRef", "signal1")).append("\" />");
        } else if ("message".equals(eventType2)) {
            bpmn.append("<messageEventDefinition messageRef=\"").append(node.getData().getOrDefault("messageRef", "msg1")).append("\" />");
        }
        bpmn.append("</boundaryEvent>\n");
    }

    /**
     * 生成抄送节点 XML
     */
    private static void generateCcNodeXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <serviceTask id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "抄送")).append("\">");
        Object cc2 = node.getData().get("cc");
        if (cc2 != null) {
            bpmn.append("<extensionElements><flowable:field name=\"cc\" stringValue=\"")
                .append(cc2.toString().replaceAll("\"", "'"))
                .append("\" /></extensionElements>");
        }
        bpmn.append("</serviceTask>\n");
    }

    /**
     * 生成子流程节点 XML
     */
    private static void generateSubProcessXml(StringBuilder bpmn, GraphSchema.FlowNode node) {
        bpmn.append("    <subProcess id=\"").append(node.getId()).append("\" name=\"").append(node.getData().getOrDefault("label", "子流程")).append("\">\n");
        // 递归生成子流程内容
        Object subNodes = node.getData().get("nodes");
        Object subEdges = node.getData().get("edges");
        if (subNodes instanceof List && subEdges instanceof List) {
            GraphSchema subSchema = new GraphSchema();
            subSchema.setNodes((List)subNodes);
            subSchema.setEdges((List)subEdges);
            String subXml = generateBpmnXml(subSchema, node.getId() + "_sub", node.getData().getOrDefault("label", "子流程").toString());
            // 只取<process>...</process>内容
            int p1 = subXml.indexOf("<process");
            int p2 = subXml.lastIndexOf("</process>");
            if (p1 > 0 && p2 > p1) {
                String inner = subXml.substring(subXml.indexOf('>', p1) + 1, p2);
                bpmn.append(inner.replaceAll("^", "      ")); // 缩进
            }
        }
        bpmn.append("    </subProcess>\n");
    }

    /**
     * 生成包含VueFlow数据的BPMN XML
     * 将VueFlow数据以注释形式嵌入到BPMN XML中，便于后续解析
     */
    public static String generateBpmnXmlWithVueFlow(GraphSchema schema, String processId, String processName) {
        String bpmnXml = generateBpmnXml(schema, processId, processName);
        
        // 将VueFlow数据转换为JSON字符串
        String vueFlowData = "{\"nodes\":" + schema.getNodes().toString() + ",\"edges\":" + schema.getEdges().toString() + "}";
        
        // 在XML开头添加VueFlow数据注释
        StringBuilder result = new StringBuilder();
        result.append("<!-- VueFlow Data: ").append(vueFlowData.replace("\"", "&quot;")).append(" -->\n");
        result.append(bpmnXml);
        
        return result.toString();
    }

    /**
     * 从BPMN XML中提取VueFlow数据
     */
    public static GraphSchema extractVueFlowFromBpmn(String bpmnXml) {
        GraphSchema schema = new GraphSchema();
        
        try {
            // 查找VueFlow数据注释
            int startIndex = bpmnXml.indexOf("<!-- VueFlow Data: ");
            if (startIndex != -1) {
                int endIndex = bpmnXml.indexOf(" -->", startIndex);
                if (endIndex != -1) {
                    String vueFlowDataStr = bpmnXml.substring(startIndex + 19, endIndex);
                    // 解码HTML实体
                    vueFlowDataStr = vueFlowDataStr.replace("&quot;", "\"");
                    
                    // 解析JSON数据
                    // 这里需要根据实际的JSON解析库来实现
                    // 暂时返回空的schema，后续可以集成Jackson或Gson
                    System.out.println("Found VueFlow data: " + vueFlowDataStr);
                }
            }
        } catch (Exception e) {
            System.err.println("Error extracting VueFlow data from BPMN: " + e.getMessage());
        }
        
        return schema;
    }

    /**
     * 生成流程版本快照数据
     */
    public static Map<String, Object> generateProcessVersionData(GraphSchema schema, String processId, String processName, String processKey) {
        Map<String, Object> versionData = new HashMap<>();
        versionData.put("processId", processId);
        versionData.put("processKey", processKey);
        versionData.put("processName", processName);
        versionData.put("graphSchema", schema);
        versionData.put("bpmnXml", generateBpmnXmlWithVueFlow(schema, processId, processName));
        versionData.put("createTime", new Date());
        return versionData;
    }

    /**
     * 获取处理人数量
     */
    private static int getAssigneeCount(Object assignees) {
        if (assignees instanceof List && !((List<?>)assignees).isEmpty()) {
            List<Map<String, Object>> assigneeList = (List<Map<String, Object>>) assignees;
            int count = 0;
            for (Map<String, Object> assigneeMap : assigneeList) {
                String type = (String) assigneeMap.get("type");
                if ("user".equals(type) && assigneeMap.get("value") instanceof List) {
                    count += ((List<?>)assigneeMap.get("value")).size();
                } else if ("role".equals(type) && assigneeMap.get("value") instanceof List) {
                    count += ((List<?>)assigneeMap.get("value")).size();
                } else if ("dept".equals(type) && assigneeMap.get("value") instanceof List) {
                    count += ((List<?>)assigneeMap.get("value")).size();
                } else if ("post".equals(type) && assigneeMap.get("value") instanceof List) {
                    count += ((List<?>)assigneeMap.get("value")).size();
                } else if ("expression".equals(type) && assigneeMap.get("value") instanceof List) {
                    count += ((List<?>)assigneeMap.get("value")).size();
                }
            }
            return count;
        }
        return 0;
    }

    /**
     * 从原始 JSON 数据生成 BPMN XML
     * 这个方法直接处理 JSON 字符串，避免转换为 GraphSchema 对象时丢失字段
     * 
     * @param graphSchemaJson 流程图的原始 JSON 数据
     * @param processId 流程ID
     * @param processName 流程名称
     * @return BPMN XML 字符串
     */
    public static String generateBpmnXmlFromJson(String graphSchemaJson, String processId, String processName) {
        try {
            // 使用 Jackson 的 ObjectMapper 将 JSON 转换为 Map，保留所有字段
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> schemaMap = objectMapper.readValue(graphSchemaJson, Map.class);
            
            StringBuilder bpmn = new StringBuilder();
            
            // 1. 收集全局信号/消息定义
            Set<String> signalSet = new HashSet<>();
            Set<String> messageSet = new HashSet<>();
            
            // 2. 生成 XML 头部
            bpmn.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            bpmn.append("<definitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:flowable=\"http://flowable.org/bpmn\" targetNamespace=\"http://www.flowable.org/processdef\">\n");
            
            // 3. 全局信号定义
            for (String sig : signalSet) {
                bpmn.append("  <signal id=\"").append(sig).append("\" name=\"").append(sig).append("\" />\n");
            }
            
            // 4. 全局消息定义
            for (String msg : messageSet) {
                bpmn.append("  <message id=\"").append(msg).append("\" name=\"").append(msg).append("\" />\n");
            }
            
            // 5. 开始流程定义
            bpmn.append("  <process id=\"").append(processId).append("\" name=\"").append(processName).append("\" isExecutable=\"true\">\n");

            // 6. 生成节点
            List<Map<String, Object>> nodes = (List<Map<String, Object>>) schemaMap.get("nodes");
            if (nodes != null) {
                for (Map<String, Object> node : nodes) {
                    generateNodeXmlFromMap(bpmn, node);
                }
            }
            
            // 7. 生成连线
            List<Map<String, Object>> edges = (List<Map<String, Object>>) schemaMap.get("edges");
            if (edges != null) {
                for (Map<String, Object> edge : edges) {
                    generateEdgeXmlFromMap(bpmn, edge);
                }
            }
            
            // 8. 结束流程定义
            bpmn.append("  </process>\n</definitions>\n");
            return bpmn.toString();
            
        } catch (Exception e) {
            throw new RuntimeException("生成 BPMN XML 失败: " + e.getMessage(), e);
        }
    }

    /**
     * 从 Map 生成节点 XML
     */
    private static void generateNodeXmlFromMap(StringBuilder bpmn, Map<String, Object> node) {
        String nodeType = (String) node.get("type");
        String nodeId = (String) node.get("id");
        Map<String, Object> nodeData = (Map<String, Object>) node.get("data");
        
        if (nodeData == null) {
            nodeData = new HashMap<>();
        }
        
        switch (nodeType) {
            case "start":
            case "input":
            case "event": // VueFlow事件节点
                generateEventNodeXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "end":
            case "output":
                generateEndEventXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "userTask":
            case "default": // 修正：default类型也生成userTask，避免IDREF未绑定
                generateUserTaskXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "serviceTask":
            case "task": // VueFlow任务节点
                generateServiceTaskXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "scriptTask":
                generateScriptTaskXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "condition":
            case "exclusiveGateway":
                generateExclusiveGatewayXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "parallelGateway":
                generateParallelGatewayXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "eventBasedGateway":
                generateEventBasedGatewayXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "gateway": {
                generateGatewayXmlFromMap(bpmn, nodeId, nodeData);
                break;
            }
            case "boundaryEvent": {
                generateBoundaryEventXmlFromMap(bpmn, nodeId, nodeData);
                break;
            }
            case "cc": // 抄送节点用serviceTask+扩展属性
                generateCcNodeXmlFromMap(bpmn, nodeId, nodeData);
                break;
            case "subProcess": {
                generateSubProcessXmlFromMap(bpmn, nodeId, nodeData);
                break;
            }
            // 可扩展更多类型
        }
    }

    /**
     * 从 Map 生成事件节点 XML
     */
    private static void generateEventNodeXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        String eventType = (String) nodeData.getOrDefault("eventType", "start");
        if ("start".equals(eventType)) {
            bpmn.append("    <startEvent id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "开始")).append("\" />\n");
        } else if ("end".equals(eventType)) {
            bpmn.append("    <endEvent id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "结束")).append("\" />\n");
        } else {
            bpmn.append("    <startEvent id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "开始")).append("\" />\n");
        }
    }

    /**
     * 从 Map 生成结束事件节点 XML
     */
    private static void generateEndEventXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <endEvent id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "结束")).append("\" />\n");
    }

    /**
     * 从 Map 生成用户任务节点 XML
     */
    private static void generateUserTaskXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <userTask id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "用户任务")).append("\"");
        
        // 处理人员配置：assignee/candidateUsers/candidateGroups
        Object assignees = nodeData.get("assignees");
        List<String> groups = new ArrayList<>();
        if (assignees instanceof List && !((List<?>)assignees).isEmpty()) {
            List<Map<String, Object>> assigneeList = (List<Map<String, Object>>) assignees;
            
            // 收集不同类型的处理人
            List<String> users = new ArrayList<>();
            List<String> roles = new ArrayList<>();
            List<String> depts = new ArrayList<>();
            List<String> posts = new ArrayList<>();
            String assignee = null;
            
            for (Map<String, Object> assigneeMap : assigneeList) {
                String type = (String) assigneeMap.get("type");
                Object value = assigneeMap.get("value");
                
                if ("user".equals(type) && value instanceof List) {
                    List<?> userList = (List<?>) value;
                    for (Object user : userList) {
                        if (user instanceof Map) {
                            String userId = String.valueOf(((Map<?, ?>) user).get("id"));
                            users.add(userId);
                            // 只有当只有一个用户时才设置为assignee
                            if (assignee == null && userList.size() == 1) {
                                assignee = userId;
                            }
                        } else if (user instanceof String) {
                            users.add((String) user);
                            if (assignee == null && userList.size() == 1) {
                                assignee = (String) user;
                            }
                        }
                    }
                } else if ("role".equals(type) && value instanceof List) {
                    List<?> roleList = (List<?>) value;
                    for (Object role : roleList) {
                        if (role instanceof Map) {
                            String roleId = String.valueOf(((Map<?, ?>) role).get("id"));
                            roles.add(roleId);
                        } else if (role instanceof String) {
                            roles.add((String) role);
                        }
                    }
                } else if ("dept".equals(type) && value instanceof List) {
                    List<?> deptList = (List<?>) value;
                    for (Object dept : deptList) {
                        if (dept instanceof Map) {
                            String deptId = String.valueOf(((Map<?, ?>) dept).get("id"));
                            depts.add(deptId);
                        } else if (dept instanceof String) {
                            depts.add((String) dept);
                        }
                    }
                } else if ("post".equals(type) && value instanceof List) {
                    List<?> postList = (List<?>) value;
                    for (Object post : postList) {
                        if (post instanceof Map) {
                            String postId = String.valueOf(((Map<?, ?>) post).get("id"));
                            posts.add(postId);
                        } else if (post instanceof String) {
                            posts.add((String) post);
                        }
                    }
                } else if ("expression".equals(type) && value instanceof List) {
                    // 处理表达式类型，如流程发起人、部门负责人等
                    List<?> exprList = (List<?>) value;
                    for (Object expr : exprList) {
                        if (expr instanceof Map) {
                            String expression = String.valueOf(((Map<?, ?>) expr).get("expression"));
                            if (expression != null && !expression.trim().isEmpty()) {
                                // 对于表达式类型，只有当只有一个表达式时才设置为assignee
                                if (assignee == null && exprList.size() == 1) {
                                    assignee = expression;
                                }
                                // 将表达式添加到候选组中，用于后续处理
                                groups.add("expr:" + expression);
                            }
                        } else if (expr instanceof String) {
                            String expression = (String) expr;
                            if (assignee == null && exprList.size() == 1) {
                                assignee = expression;
                            }
                            groups.add("expr:" + expression);
                        }
                    }
                }
            }
            
            // 设置assignee（只有当只有一个处理人时才设置）
            if (assignee != null) {
                bpmn.append(" flowable:assignee=\"").append(assignee).append("\"");
            }
            
            // 设置candidateUsers（所有用户）
            if (!users.isEmpty()) {
                bpmn.append(" flowable:candidateUsers=\"").append(String.join(",", users)).append("\"");
            }
            
            // 设置candidateGroups（角色、部门、岗位、表达式）
            groups.addAll(roles);
            groups.addAll(depts);
            groups.addAll(posts);
            if (!groups.isEmpty()) {
                bpmn.append(" flowable:candidateGroups=\"").append(String.join(",", groups)).append("\"");
            }
        }
        
        bpmn.append(">");
        
        // 收集所有扩展元素
        StringBuilder extensionElements = new StringBuilder();
        
        // 监听器
        Object listeners = nodeData.get("listeners");
        if (listeners instanceof List) {
            for (Object l : (List<?>)listeners) {
                if (l instanceof Map) {
                    Map listener = (Map)l;
                    extensionElements.append("<flowable:taskListener event=\"")
                        .append(listener.getOrDefault("event", "create")).append("\"");
                    if ("custom".equals(listener.get("type"))) {
                        extensionElements.append(" class=\"").append(listener.getOrDefault("class", "")).append("\"");
                    }
                    extensionElements.append(" />");
                }
            }
        }
        
        // 添加自定义任务监听器，用于处理用户、角色、部门、岗位到用户的映射
        // 为所有用户任务节点都添加，确保人员配置能正确处理
        extensionElements.append("<flowable:taskListener event=\"create\" class=\"com.xueyi.workflow.listener.CustomTaskListener\" />");
        
        // 抄送配置
        Object cc = nodeData.get("cc");
        Object notifyMethods = nodeData.get("notifyMethods");
        if (cc != null || notifyMethods != null) {
            if (cc != null) {
                extensionElements.append("<flowable:field name=\"cc\" stringValue=\"")
                    .append(cc.toString().replaceAll("\"", "'"))
                    .append("\" />");
            }
            if (notifyMethods != null) {
                extensionElements.append("<flowable:field name=\"notifyMethods\" stringValue=\"")
                    .append(notifyMethods.toString().replaceAll("\"", "'"))
                    .append("\" />");
            }
        }
        
        // 如果有扩展元素，添加extensionElements标签
        if (extensionElements.length() > 0) {
            bpmn.append("<extensionElements>").append(extensionElements).append("</extensionElements>");
        }
        
        // 会签（多实例）
        Object countersign = nodeData.get("countersign");
        if (countersign instanceof Map) {
            Map countersignMap = (Map)countersign;
            String countersignType = (String) countersignMap.get("type");
            // 只有当type不为null且不为空字符串时才生成多实例配置
            if (countersignType != null && !countersignType.trim().isEmpty()) {
                bpmn.append("<multiInstanceLoopCharacteristics isSequential=\"")
                    .append("serial".equals(countersignType) ? "true" : "false")
                    .append("\">");
                
                // 处理循环数据源
                String loopDataInputRef = (String) countersignMap.get("loopDataInputRef");
                if ("assigneeList".equals(loopDataInputRef)) {
                    // 根据人员配置自动生成循环数据
                    bpmn.append("<loopDataInputRef>assigneeList</loopDataInputRef>");
                    bpmn.append("<inputDataItem name=\"assigneeList\" />");
                } else if ("customVariable".equals(loopDataInputRef)) {
                    // 使用自定义变量
                    String customVariableName = (String) countersignMap.get("customVariableName");
                    if (customVariableName != null && !customVariableName.trim().isEmpty()) {
                        bpmn.append("<loopDataInputRef>").append(customVariableName).append("</loopDataInputRef>");
                    } else {
                        // 默认使用assigneeList
                        bpmn.append("<loopDataInputRef>assigneeList</loopDataInputRef>");
                    }
                } else {
                    // 默认使用loopCardinality，根据人员数量设置
                    int assigneeCount = getAssigneeCount(assignees);
                    if (assigneeCount > 0) {
                        bpmn.append("<loopCardinality>").append(assigneeCount).append("</loopCardinality>");
                    } else {
                        bpmn.append("<loopCardinality>1</loopCardinality>");
                    }
                }
                
                // 处理完成条件
                String completionType = (String) countersignMap.get("completionType");
                if ("all".equals(completionType)) {
                    // 全部完成
                    bpmn.append("<completionCondition>${nrOfCompletedInstances == nrOfInstances}</completionCondition>");
                } else if ("minPass".equals(completionType)) {
                    // 最少通过数
                    Object minPass = countersignMap.get("minPass");
                    if (minPass != null) {
                        bpmn.append("<completionCondition>${nrOfCompletedInstances >= ").append(minPass).append("}</completionCondition>");
                    }
                } else if ("maxPass".equals(completionType)) {
                    // 最多通过数
                    Object maxPass = countersignMap.get("maxPass");
                    if (maxPass != null) {
                        bpmn.append("<completionCondition>${nrOfCompletedInstances >= ").append(maxPass).append("}</completionCondition>");
                    }
                } else if ("percentage".equals(completionType)) {
                    // 百分比
                    Object percentage = countersignMap.get("percentage");
                    if (percentage != null) {
                        bpmn.append("<completionCondition>${nrOfCompletedInstances >= (nrOfInstances * ").append(percentage).append(" / 100)}</completionCondition>");
                    }
                } else {
                    // 默认：最少通过数（兼容旧版本）
                    Object minPass = countersignMap.get("minPass");
                    if (minPass != null) {
                        bpmn.append("<completionCondition>${nrOfCompletedInstances >= ").append(minPass).append("}</completionCondition>");
                    }
                }
                
                bpmn.append("</multiInstanceLoopCharacteristics>");
            }
        }
        
        bpmn.append("</userTask>\n");
    }

    /**
     * 从 Map 生成服务任务节点 XML
     */
    private static void generateServiceTaskXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <serviceTask id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "服务任务")).append("\"");
        // 服务任务配置
        Object serviceClass = nodeData.get("serviceClass");
        if (serviceClass != null) {
            bpmn.append(" flowable:class=\"").append(serviceClass.toString()).append("\"");
        }
        bpmn.append(">");
        
        // 抄送配置
        Object serviceCc = nodeData.get("cc");
        Object serviceNotifyMethods = nodeData.get("notifyMethods");
        if (serviceCc != null || serviceNotifyMethods != null) {
            bpmn.append("<extensionElements>");
            if (serviceCc != null) {
                bpmn.append("<flowable:field name=\"cc\" stringValue=\"")
                    .append(serviceCc.toString().replaceAll("\"", "'"))
                    .append("\" />");
            }
            if (serviceNotifyMethods != null) {
                bpmn.append("<flowable:field name=\"notifyMethods\" stringValue=\"")
                    .append(serviceNotifyMethods.toString().replaceAll("\"", "'"))
                    .append("\" />");
            }
            bpmn.append("</extensionElements>");
        }
        bpmn.append("</serviceTask>\n");
    }

    /**
     * 从 Map 生成脚本任务节点 XML
     */
    private static void generateScriptTaskXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <scriptTask id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "脚本任务")).append("\" scriptFormat=\"groovy\">");
        Object script = nodeData.get("script");
        if (script != null) bpmn.append(script);
        bpmn.append("</scriptTask>\n");
    }

    /**
     * 从 Map 生成条件网关节点 XML
     */
    private static void generateExclusiveGatewayXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <exclusiveGateway id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "条件网关")).append("\" />\n");
    }

    /**
     * 从 Map 生成并行网关节点 XML
     */
    private static void generateParallelGatewayXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <parallelGateway id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "并行网关")).append("\" />\n");
    }

    /**
     * 从 Map 生成事件网关节点 XML
     */
    private static void generateEventBasedGatewayXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <eventBasedGateway id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "事件网关")).append("\" />\n");
    }

    /**
     * 从 Map 生成网关节点 XML
     */
    private static void generateGatewayXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        // 根据网关类型生成不同的网关
        String gatewayType = (String) nodeData.getOrDefault("gatewayType", "exclusive");
        String gatewayName = (String) nodeData.getOrDefault("label", "网关");
        switch (gatewayType) {
            case "exclusive":
                bpmn.append("    <exclusiveGateway id=\"").append(nodeId).append("\" name=\"").append(gatewayName).append("\" />\n");
                break;
            case "parallel":
                bpmn.append("    <parallelGateway id=\"").append(nodeId).append("\" name=\"").append(gatewayName).append("\" />\n");
                break;
            case "event":
                bpmn.append("    <eventBasedGateway id=\"").append(nodeId).append("\" name=\"").append(gatewayName).append("\" />\n");
                break;
            default:
                bpmn.append("    <exclusiveGateway id=\"").append(nodeId).append("\" name=\"").append(gatewayName).append("\" />\n");
                break;
        }
    }

    /**
     * 从 Map 生成边界事件节点 XML
     */
    private static void generateBoundaryEventXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <boundaryEvent id=\"").append(nodeId).append("\" attachedToRef=\"").append(nodeData.getOrDefault("attachedTo", "")).append("\">");
        String eventType2 = (String) nodeData.getOrDefault("eventType", "timer");
        if ("timer".equals(eventType2)) {
            bpmn.append("<timerEventDefinition><timeDuration>").append(nodeData.getOrDefault("duration", "PT1H")).append("</timeDuration></timerEventDefinition>");
        } else if ("signal".equals(eventType2)) {
            bpmn.append("<signalEventDefinition signalRef=\"").append(nodeData.getOrDefault("signalRef", "signal1")).append("\" />");
        } else if ("message".equals(eventType2)) {
            bpmn.append("<messageEventDefinition messageRef=\"").append(nodeData.getOrDefault("messageRef", "msg1")).append("\" />");
        }
        bpmn.append("</boundaryEvent>\n");
    }

    /**
     * 从 Map 生成抄送节点 XML
     */
    private static void generateCcNodeXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <serviceTask id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "抄送")).append("\">");
        Object cc2 = nodeData.get("cc");
        if (cc2 != null) {
            bpmn.append("<extensionElements><flowable:field name=\"cc\" stringValue=\"")
                .append(cc2.toString().replaceAll("\"", "'"))
                .append("\" /></extensionElements>");
        }
        bpmn.append("</serviceTask>\n");
    }

    /**
     * 从 Map 生成子流程节点 XML
     */
    private static void generateSubProcessXmlFromMap(StringBuilder bpmn, String nodeId, Map<String, Object> nodeData) {
        bpmn.append("    <subProcess id=\"").append(nodeId).append("\" name=\"").append(nodeData.getOrDefault("label", "子流程")).append("\">\n");
        // 递归生成子流程内容
        Object subNodes = nodeData.get("nodes");
        Object subEdges = nodeData.get("edges");
        if (subNodes instanceof List && subEdges instanceof List) {
            // 这里可以递归处理子流程，暂时简化处理
            bpmn.append("      <!-- 子流程内容 -->\n");
        }
        bpmn.append("    </subProcess>\n");
    }

    /**
     * 从 Map 生成连线 XML
     * 核心逻辑：直接从 Map 中读取连线的所有字段，包括条件表达式
     */
    private static void generateEdgeXmlFromMap(StringBuilder bpmn, Map<String, Object> edge) {
        String source = (String) edge.get("source");
        String target = (String) edge.get("target");
        
        // 1. 生成连线基础信息
        bpmn.append("    <sequenceFlow id=\"").append(source).append("_to_").append(target)
            .append("\" sourceRef=\"").append(source).append("\" targetRef=\"").append(target).append("\"");
        
        // 2. 检查连线是否包含条件表达式
        // 直接从 Map 中读取，保留所有字段
        String conditionType = (String) edge.get("conditionType");
        String conditionExpression = (String) edge.get("conditionExpression");
        String scriptContent = (String) edge.get("scriptContent");
        String scriptLanguage = (String) edge.get("scriptLanguage");
        
        // 3. 处理条件表达式
        if (conditionType != null && !conditionType.trim().isEmpty()) {
            if ("expression".equals(conditionType) && conditionExpression != null && !conditionExpression.trim().isEmpty()) {
                bpmn.append(">\n      <conditionExpression xsi:type=\"tFormalExpression\">")
                    .append(conditionExpression)
                    .append("</conditionExpression>\n    </sequenceFlow>\n");
                return;
            } else if ("script".equals(conditionType) && scriptContent != null && !scriptContent.trim().isEmpty()) {
                String language = scriptLanguage != null ? scriptLanguage : "javascript";
                bpmn.append(">\n      <conditionExpression xsi:type=\"tFormalExpression\" language=\"").append(language).append("\">")
                    .append(scriptContent)
                    .append("</conditionExpression>\n    </sequenceFlow>\n");
                return;
            }
        }
        
        // 4. 检查 data 字段中的条件配置
        Object edgeData = edge.get("data");
        if (edgeData instanceof Map) {
            Map<String, Object> dataMap = (Map<String, Object>) edgeData;
            String dataConditionType = (String) dataMap.get("conditionType");
            if (dataConditionType != null && !dataConditionType.trim().isEmpty()) {
                if ("expression".equals(dataConditionType)) {
                    String dataConditionExpression = (String) dataMap.get("conditionExpression");
                    if (dataConditionExpression != null && !dataConditionExpression.trim().isEmpty()) {
                        bpmn.append(">\n      <conditionExpression xsi:type=\"tFormalExpression\">")
                            .append(dataConditionExpression)
                            .append("</conditionExpression>\n    </sequenceFlow>\n");
                        return;
                    }
                } else if ("script".equals(dataConditionType)) {
                    String dataScriptLanguage = (String) dataMap.getOrDefault("scriptLanguage", "javascript");
                    String dataScriptContent = (String) dataMap.get("scriptContent");
                    if (dataScriptContent != null && !dataScriptContent.trim().isEmpty()) {
                        bpmn.append(">\n      <conditionExpression xsi:type=\"tFormalExpression\" language=\"").append(dataScriptLanguage).append("\">")
                            .append(dataScriptContent)
                            .append("</conditionExpression>\n    </sequenceFlow>\n");
                        return;
                    }
                }
            }
        }
        
        // 5. 如果没有找到条件，生成无条件连线
        bpmn.append(" />\n");
    }
} 